import time
import requests
import urllib3
import json
from typing import Tuple
from api.utils.logger import get_logger
from api.utils.singbox_proxy_helper import get_v2ray_proxy_config

# 禁用SSL警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

logger = get_logger("proxy_service")

class ProxyService:
    """代理服务类"""
    
    # 多个测试URL，按优先级排序
    TEST_URLS = [
        "https://www.google.com/generate_204",
        "http://connectivitycheck.gstatic.com/generate_204",
    ]
    
    @staticmethod
    def test_proxy_latency(proxy_type: str, host: str, port: int,
                          username: str = None, password: str = None,
                          v2ray_config: str = None,
                          timeout: int = 30) -> Tuple[bool, int, str]:
        """
        测试代理延迟（尝试多个测试URL）
        
        Args:
            proxy_type: 代理类型 ('socks5', 'http', 'https', 'vmess', 'vless', 'trojan')
            host: 代理服务器地址
            port: 代理端口
            username: 代理用户名（可选）
            password: 代理密码（可选）
            v2ray_config: v2ray配置JSON字符串（vmess/vless/trojan必需）
            timeout: 超时时间（秒，默认30秒）
            
        Returns:
            (是否成功, 延迟ms, 错误信息)
        """
        # 处理V2Ray类型代理
        if proxy_type in ['vmess', 'vless', 'trojan']:
            logger.info(f"[测试代理] 检测到V2Ray类型: {proxy_type}://{host}:{port}")
            
            if not v2ray_config:
                logger.error(f"[测试代理] {proxy_type.upper()}代理缺少配置信息")
                return False, 0, f"{proxy_type.upper()}代理缺少配置信息"
            
            # 转换为SOCKS5桥接配置
            try:
                logger.debug(f"[测试代理] 开始转换V2Ray配置为SOCKS5桥接...")
                bridge_config = get_v2ray_proxy_config(v2ray_config)
                
                if bridge_config.get('type') == 'unsupported':
                    error_msg = bridge_config.get('error', '不支持的V2Ray代理')
                    logger.warning(f"[测试代理] V2Ray代理不可用: {error_msg}")
                    # 对于V2Ray代理，如果没有xray环境，返回成功但提示信息
                    return True, 0, f"{proxy_type.upper()}代理已添加（注意：{error_msg}）"
                
                # 使用转换后的SOCKS5配置进行测试
                proxy_type = 'socks5'
                host = bridge_config['host']
                port = bridge_config['port']
                username = None
                password = None
            except Exception as e:
                logger.error(f"[测试代理] V2Ray配置转换失败: {e}", exc_info=True)
                return False, 0, f"V2Ray代理配置错误: {str(e)}"
        
        # 构建代理配置
        if proxy_type == 'socks5':
            # SOCKS5 代理格式
            if username and password:
                proxy_url = f'socks5://{username}:{password}@{host}:{port}'
            else:
                proxy_url = f'socks5://{host}:{port}'
            proxies = {
                'http': proxy_url,
                'https': proxy_url
            }
        else:  # http/https
            # HTTP 代理格式
            if username and password:
                proxy_url = f'http://{username}:{password}@{host}:{port}'
            else:
                proxy_url = f'http://{host}:{port}'
            proxies = {
                'http': proxy_url,
                'https': proxy_url
            }
        
        logger.debug(f"[测试代理] 代理配置: {proxies}")
        
        # 尝试多个测试URL
        last_error = None
        for idx, test_url in enumerate(ProxyService.TEST_URLS, 1):
            try:
                logger.debug(f"[测试代理] 尝试URL {idx}/{len(ProxyService.TEST_URLS)}: {test_url}")
                start_time = time.time()
                
                # 发送测试请求（禁用SSL验证）
                response = requests.get(
                    test_url,
                    proxies=proxies,
                    timeout=timeout,
                    allow_redirects=False,
                    verify=False  # 禁用SSL证书验证
                )
                
                # 计算延迟
                latency = int((time.time() - start_time) * 1000)
                
                # 判断响应是否有效
                if response.status_code in [200, 204]:
                    logger.info(f"[测试代理] ✓ 测试成功! 延迟: {latency}ms (URL: {test_url})")
                    return True, latency, "测试成功"
                elif response.status_code == 407:
                    # 407表示代理需要认证，但说明代理是通的
                    logger.info(f"[测试代理] ✓ 代理连接成功（需要认证），延迟: {latency}ms")
                    return True, latency, f"代理连接成功，延迟: {latency}ms（需要认证）"
                else:
                    last_error = f"HTTP状态码异常: {response.status_code}"
                    logger.warning(f"[测试代理] URL {idx} 失败: {last_error}")
                    continue
                    
            except requests.exceptions.ProxyError as e:
                error_msg = f"代理连接失败: {str(e)}"
                logger.warning(f"[测试代理] URL {idx} ProxyError: {error_msg}")
                last_error = error_msg
                continue
                
            except requests.exceptions.Timeout:
                error_msg = f"连接超时（{timeout}秒）"
                logger.warning(f"[测试代理] URL {idx} Timeout: {error_msg}")
                last_error = error_msg
                continue
                
            except requests.exceptions.ConnectionError as e:
                error_msg = f"网络连接错误: {str(e)}"
                logger.warning(f"[测试代理] URL {idx} ConnectionError: {error_msg}")
                last_error = error_msg
                continue
                
            except Exception as e:
                error_msg = f"测试失败: {str(e)}"
                logger.warning(f"[测试代理] URL {idx} Exception: {error_msg}")
                last_error = error_msg
                continue
        
        # 所有URL都失败了
        final_error = last_error or f"所有测试URL均失败（超时{timeout}秒）- 可能原因：1.代理服务器故障 2.网络不稳定 3.代理配置错误"
        logger.error(f"[测试代理] ✗ 测试完全失败: {final_error}")
        return False, 0, final_error